#ifndef DRAGGABLERECTITEM_H
#define DRAGGABLERECTITEM_H

#include <QObject>
#include <QGraphicsRectItem>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsSceneHoverEvent>

/**
 * @brief 可拖动的矩形项类
 * 支持矩形的移动和八个方向的大小调整
 */
class DraggableRectItem : public QObject, public QGraphicsRectItem
{
    Q_OBJECT

public:
    /**
     * @brief 调整手柄类型枚举
     */
    enum ResizeHandle {
        NoHandle,
        LeftTop,
        Top,
        RightTop,
        Right,
        RightBottom,
        Bottom,
        LeftBottom,
        Left
    };

    /**
     * @brief 构造函数
     * @param rect 初始矩形
     * @param parent 父图形项
     */
    explicit DraggableRectItem(const QRectF &rect, QGraphicsItem *parent = nullptr);
    
    // 为了让QObject正常工作，需要重写QGraphicsItem的type方法
    enum { Type = UserType + 1 };
    int type() const override { return Type; }
    
    /**
     * @brief 构造函数
     * @param x 矩形左上角x坐标
     * @param y 矩形左上角y坐标
     * @param width 矩形宽度
     * @param height 矩形高度
     * @param parent 父图形项
     */
    explicit DraggableRectItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = nullptr);
    
    /**
     * @brief 构造函数
     * @param parent 父图形项
     */
    explicit DraggableRectItem(QGraphicsItem *parent = nullptr);

    /**
     * @brief 设置是否启用大小调整功能
     * @param enabled true表示启用，false表示禁用
     */
    void setResizable(bool enabled);
    
    /**
     * @brief 获取是否启用大小调整功能
     * @return true表示启用，false表示禁用
     */
    bool isResizable() const;
    
    /**
     * @brief 设置矩形最小尺寸
     * @param size 最小尺寸
     */
    void setMinimumSize(const QSizeF &size);
    
    /**
     * @brief 获取矩形最小尺寸
     * @return 最小尺寸
     */
    QSizeF minimumSize() const;

protected:
    /**
     * @brief 鼠标按下事件处理
     * @param event 鼠标事件
     */
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
    
    /**
     * @brief 鼠标移动事件处理
     * @param event 鼠标事件
     */
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
    
    /**
     * @brief 鼠标释放事件处理
     * @param event 鼠标事件
     */
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
    
    /**
     * @brief 鼠标悬停进入事件处理
     * @param event 悬停事件
     */
    void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
    
    /**
     * @brief 鼠标悬停移动事件处理
     * @param event 悬停事件
     */
    void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
    
    /**
     * @brief 鼠标悬停离开事件处理
     * @param event 悬停事件
     */
    void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
    
    /**
     * @brief 绘制事件处理
     * @param painter 绘制器
     * @param option 样式选项
     * @param widget 关联窗口部件
     */
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;

private:
    /**
     * @brief 根据鼠标位置确定调整手柄类型
     * @param pos 鼠标位置
     * @return 调整手柄类型
     */
    ResizeHandle getHandleAt(const QPointF &pos);
    
    /**
     * @brief 根据调整手柄类型设置光标
     * @param handle 调整手柄类型
     */
    void setCursorForHandle(ResizeHandle handle);
    
    /**
     * @brief 处理矩形大小调整
     * @param pos 鼠标位置
     */
    void resizeRect(const QPointF &pos);

signals:
    /**
     * @brief 矩形位置变化信号
     */
    void positionChanged();
    
    /**
     * @brief 矩形大小变化信号
     */
    void sizeChanged();

protected:
    /**
     * @brief 图形项变化事件
     * @param change 变化类型
     * @param value 变化值
     * @return 变化后的值
     */
    QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;

private:
    bool m_isResizable;       // 是否启用大小调整
    bool m_isDragging;        // 是否正在拖动
    bool m_isResizing;        // 是否正在调整大小
    ResizeHandle m_currentHandle; // 当前操作的调整手柄
    QPointF m_dragStartPos;   // 拖动起始位置
    QPointF m_itemStartPos;   // 项目起始位置
    QRectF m_startRect;       // 起始矩形
    QSizeF m_minimumSize;     // 最小尺寸
    qreal m_handleSize;       // 调整手柄大小
};

#endif // DRAGGABLERECTITEM_H